import { _decorator, Component, Node, Vec3, view, RigidBody2D, Collider2D, Contact2DType, IPhysics2DContact, director, Director, instantiate, Vec2 } from 'cc';
import { BulletType } from '../Event/EnumDefine';
import { Block } from '../Block/Block';
import Common from '../Config/Common';
import { ExplodeBomb } from './ExplodeBomb';
const { ccclass, property } = _decorator;

@ccclass('Bullet')
export class Bullet extends Component {
    /** 子弹类型 */
    type: BulletType = BulletType.Normal;
    /** 子弹的方向 */
    direction: Vec3 = new Vec3();
    /** 子弹的攻击伤害 */
    damage: number = 1;
    /** 是否在碰撞后已处理销毁，不在此组件内检测超出屏幕销毁 */
    isCollisionDestroy: boolean = false;
    /** 子弹射击速度 */
    shootSpeed: number = 0;
    /**  */
    colliderTime: number = 0;
    /** 爆炸弹是否已经爆炸过 */
    isExploded = false;

    _removeBullet: Function = null;

    onEnable() {
        // 监听碰撞事件
        let collider = this.getComponent(Collider2D);
        if (collider) {
            collider.on(Contact2DType.BEGIN_CONTACT, this.onBeginContact, this);
            collider.on(Contact2DType.END_CONTACT, this.onEndContact, this);
        } else {
            console.warn("Bullet Node Not add Collider2D Component.");
        }
    }
    onDisable() {
        // 取消监听碰撞事件
        const collider = this.getComponent(Collider2D);
        if (collider) {
            collider.off(Contact2DType.BEGIN_CONTACT, this.onBeginContact, this);
            collider.off(Contact2DType.END_CONTACT, this.onEndContact, this);
        }
    }

    set_cb_removeBullet(cb: Function) {
        this._removeBullet = cb;
    }

    onBeginContact(selfCollider: Collider2D, otherCollider: Collider2D, contact: IPhysics2DContact | null) {
        // 只在两个碰撞体开始接触时被调用一次
        const selfNode = selfCollider.node;
        const otherNode = otherCollider.node;
        const bulletNameList = ['Bullet', 'Bullet_UZI', 'Bullet_Bomb'];
        const selfItemIndex = bulletNameList.indexOf(selfNode.name)
        const otherItemIndex = bulletNameList.indexOf(otherNode.name)
        if (selfItemIndex !== -1 && otherNode.name === 'Block') {
            this.onHandleCollider(otherNode, selfNode)
        } else if (selfNode.name === "Block" && otherItemIndex !== -1) {
            this.onHandleCollider(selfNode, otherNode)
        }
    }
    onEndContact(selfCollider: Collider2D, otherCollider: Collider2D, contact: IPhysics2DContact | null) {}

    /** 处理子弹碰撞 */
    onHandleCollider(blockNode: Node, bulletNode: Node) {
        this.colliderTime++;
        if (blockNode.getComponent(Block)) {
            blockNode.getComponent(Block).onDamage(this.damage);
        }
        if (this.type === BulletType.Normal) {
            this.explodeBullet();
        }
        // 炸弹类型，需要触发一个爆炸范围伤害
        else if (this.type === BulletType.Bomb) {
            if (this.isExploded) {
                return;
            }
            this.isExploded = true;
            this.explodeBomb();
            // 子弹爆炸里会处理销毁
            this.isCollisionDestroy = true;
            // 等待物理回调销毁
            director.once(Director.EVENT_AFTER_PHYSICS, () => {
                if (bulletNode) {
                    this.destroy();
                    const childTuowei = this.node.getChildByName('tuowei');
                    childTuowei.children.forEach((icon) => { icon.active = false; });
                    const childPoint = this.node.getChildByName('point');
                    childPoint.children.forEach((icon) => { icon.active = false; });
                }
            })
            return;
        }
        // if(this.colliderTime <3){
        //     return;
        // }
        this.isCollisionDestroy = true;
        // 等待物理回调销毁
        director.once(Director.EVENT_AFTER_PHYSICS, () => {
            if (bulletNode) {
                this._removeBullet && this._removeBullet(this.node);
            }
        })
    }

    // 爆炸效果
    explodeBomb() {
        const bomb = this.node.parent.getChildByName('BombExplode');
        if (bomb) {
            let explodeNode = instantiate(bomb);
            explodeNode.active = true;
            explodeNode.parent = this.node;
            explodeNode.getComponent(ExplodeBomb).damage = this.damage;
        }
    }

    explodeBullet(){
        const bomb = this.node.parent.getChildByName('BulletExplode');
        if (bomb) {
            let explodeNode = instantiate(bomb);
            explodeNode.parent = this.node.parent;
            explodeNode.position = this.node.position;
            explodeNode.active = true;
        }
    }

    update(deltaTime: number) {
        if (this.isCollisionDestroy) {
            return;
        }

        // 普通子弹(从一点散射，再直射)
        if (this.type == BulletType.Normal) {
            let dis = 1;
            let angle = -this.node.angle;
            if (angle < -dis) {
                angle += dis
            }
            else if (angle > dis) {
                angle -= dis;
            }
            else {
                angle = 0;
            }
            this.node.angle = -angle;
            // 计算子弹的方向向量
            let radians = angle * Math.PI / 180;
            let direction = new Vec2(Math.sin(radians), Math.cos(radians)).normalize();
            // 设置子弹的速度
            let rigidBody = this.node.getComponent(RigidBody2D);
            if (rigidBody) {
                rigidBody.linearVelocity = direction.multiplyScalar(this.shootSpeed);
            }
        }

        const screenSize = Common.instance.getScreenSize();
        const bulletPos = this.node.position;
        // 检测子弹是否飞出屏幕外
        if (
            bulletPos.x < -screenSize.width / 2 ||
            bulletPos.x > screenSize.width / 2 ||
            bulletPos.y < -screenSize.height / 2 ||
            bulletPos.y > screenSize.height / 2
        ) {
            this._removeBullet && this._removeBullet(this.node);
        }
    }
}
